# PROBLEM STATEMENT:
# ==================
# Given a list of space separated words, reverse the order of the words. Each
# input string contains L letters and W words. An input string will only consist
# of letters and space characters. There will be exactly one space character
# between each pair of consecutive words. For instance, the reverse of “this is
# a test” is “test a is this”, the reverse of “foobar” is “foobar”, and the
# reverse of “all your base” is “base your all”.
# 
# After we solved the reverse-words problem in an exercise a few weeks ago, a
# reader complained that the suggested solution was too simple because it used
# library functions to split the words and later to rejoin them; he also thought
# the exercise should include a restriction that the string had to be reversed
# in-place. I’m not sure about either of the objections, but we’ll take the
# opportunity to revisit a classic interview question. We’ll also eliminate the
# letters-only and single-space-between-words restrictions of the original
# exercise from Google. Thus, here are some sample inputs and their associated
# outputs; note especially the placements of leading and trailing spaces
#
# SOLUTIONS:
# ==========
# The naive solution is simple. We are using regex library to capture two
# possibilities: spaces and non-spaces. With tokenized string, it's as easy as
# going through the list of words and put each into the output list, then join
# them into a big string.
#
# The other solution is to swap characters at the front and back one by one. So
# we get a completely reversed string. The next step is to tokenize each word.
#


import re
from UserString import MutableString

tokenizer = re.compile(r'\S+|\s+')

def reverse_words(thestr):
   words = tokenizer.findall(thestr)
   reverse_list = []
   for w in words:
      reverse_list[:0] = [w]
   return ''.join(reverse_list)

def reverse_words_better(thestr):
   def reverse_str(s):
      ms = MutableString(s)
      stopPoint = len(thestr) // 2
      for i in range(0, stopPoint):
         ms[i], ms[-(i+1)] = m[-(i+1)], m[i]
      return str(s)
   rstr = reverse_str(thestr)
   # to do further here. not done


def show_reverse(str):
   print('"%s" => "%s"' % (str, reverse_words(str)))

show_reverse('')
show_reverse(' ')
show_reverse('  ')
show_reverse('hello')
show_reverse('hello ')
show_reverse(' hello')
show_reverse('the quick brown fox')
show_reverse('the quick  brown fox')
show_reverse('the quick  brown 42 fox!')
